﻿using System.Collections.Concurrent;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using KinonekoSoftware.CodariaDB.Core;
using KinonekoSoftware.CodariaDB.Presets;
using KinonekoSoftware.Foundation.UI;
using KinonekoSoftware.Studio.Utils;

namespace KinonekoSoftware.Studio.Resources.Converters
{
    public sealed class ImageConverter : ImageConverterBase<ImageSystem>
    {
        private static readonly Lazy<BitmapImage> DefaultImage = new Lazy<BitmapImage>(() => new BitmapImage(new Uri(URI_IMAGE_MASKED_ICON)));


        protected override ImageSource GetFallbackImage() => DefaultImage.Value;

        protected override Stream GetStream(string id)
        {
            try
            {
                return Engine.OpenThumbnail(id);
            }
            catch
            {
                return null;
            }
        }

        //
        // /// <summary>
        // /// 根据指定的ID获取图片。
        // /// </summary>
        // /// <param name="id">图片的ID</param>
        // /// <returns>返回指定ID所对应的图片或者返回回滚图片。</returns>
        // protected override ImageSource GetImage(string id)
        // {
        //
        //     if (string.IsNullOrEmpty(id))
        //     {
        //         return GetFallbackImage();
        //     }
        //
        //     BitmapImage bi;
        //     
        //     if (!Cache.TryGetValue(id, out var wBI))
        //     {
        //         var stream = GetStream(id);
        //         if (stream is null)
        //         {
        //             return GetFallbackImage();
        //         }
        //         
        //         bi  = GetImage(stream);
        //         wBI = new WeakReference<BitmapImage>(bi);
        //         Cache.TryAdd(id, wBI);
        //         return bi;
        //     }
        //
        //     if (!wBI.TryGetTarget(out bi))
        //     {
        //         var stream = GetStream(id);
        //         bi = GetImage(stream);
        //         wBI.SetTarget(bi);
        //     }
        //     
        //     return bi;
        // }
    }


    public sealed class FastImageConverter : ImageConverterBase<ImageSystem>
    {
        private static readonly Lazy<BitmapImage> DefaultImage = new Lazy<BitmapImage>(() => new BitmapImage(new Uri(URI_IMAGE_MASKED_ICON)));


        protected override ImageSource GetFallbackImage() => DefaultImage.Value;

        protected override Stream GetStream(string id)
        {
            try
            {
                return Engine.Open(id);
            }
            catch
            {
                return null;
            }
        }

        protected override BitmapImage GetImage(string id, Stream stream)
        {
            int n;
            var ms      = new MemoryStream((int)stream.Length);
            var splited = id.Split('_');
            var w       = int.TryParse(splited[1], out n) ? n : 0;
            var h       = int.TryParse(splited[2], out n) ? n : 0;
            var bi      = new BitmapImage();
            var factor  = h / 1080d;

            stream.CopyTo(ms);
            stream.Dispose();

            //
            //
            ms.Seek(0, SeekOrigin.Begin);


            bi.BeginInit();
            bi.StreamSource      = ms;
            bi.DecodePixelHeight = h > 1080 ? 1080 : h;
            bi.DecodePixelWidth  = (int)(w > 1920 ? w / factor : w);
            bi.EndInit();
            if (bi.CanFreeze) bi.Freeze();
            return bi;
        }
    }


    public sealed class FastThumbnailConverter : ImageConverterBase<ImageSystem>
    {
        private static readonly Lazy<BitmapImage> DefaultImage = new Lazy<BitmapImage>(() => new BitmapImage(new Uri(URI_IMAGE_MASKED_ICON)));


        protected override ImageSource GetFallbackImage() => DefaultImage.Value;
        
        protected override ConcurrentDictionary<string, WeakReference<object>> GetCache() => Platform.ThumbnailCache;

        protected override Stream GetStream(string id)
        {
            try
            {
                return Engine.Open(id);
            }
            catch
            {
                return null;
            }
        }

        protected override BitmapImage GetImage(string id, Stream stream)
        {
            int n;
            var ms      = new MemoryStream((int)stream.Length);
            var splited = id.Split('_');
            var w       = int.TryParse(splited[1], out n) ? n : 0;
            var h       = int.TryParse(splited[2], out n) ? n : 0;
            var bi      = new BitmapImage();
            var factor  = h / 320d;

            stream.CopyTo(ms);
            stream.Dispose();

            //
            //
            ms.Seek(0, SeekOrigin.Begin);


            bi.BeginInit();
            bi.StreamSource      = ms;
            bi.DecodePixelHeight = h > 320 ? 320 : h;
            bi.DecodePixelWidth  = (int)(w > 480 ? w / factor : w);
            bi.EndInit();
            if (bi.CanFreeze) bi.Freeze();
            return bi;
        }
    }
}